package pl.edu.agh.gt.real;

import org.apache.log4j.Logger;

import pl.edu.agh.gt.data.Rate;
import pl.edu.agh.gt.data.RatesHistory;
import pl.edu.agh.gt.gui.ChartDisplay;
import pl.edu.agh.gt.stock.Stock;
import pl.edu.agh.gt.stock.StockListener;
import pl.edu.agh.gt.stock.Trader;
import pl.edu.agh.gt.stock.TraderListener;
import pl.edu.agh.gt.strategy.GreedyStrategy;
import pl.edu.agh.gt.strategy.Strategy;

public class RealTrader implements TraderListener, StockListener {
	
	private final static Logger log = Logger.getLogger(RealTrader.class);

	private static final int MAX_IN_THE_MARKET = 24; // proportional to windowSize ? XXX olewamy
	
	private TraderPool myPool;
	
	private Trader trader;

	private int inTheMarketTime;
	float totalEarn;
	
	public RealTrader(TraderPool pool, Strategy s) {
		myPool = pool;
		pool.stock.addListener(this);
		
		createNewTrader(s);	
	}	
	
	@Override
	public void onClose(Trader t, Rate rate) {
		
		log.info("CLOSING");
		
		float earn = (trader.baseCurrency - Trader.INITIAL_VALUE);
		
		if( earn <= GreedyStrategy.maxLoss ) { // usuwamy gdy przegrala
					
			showTraderPerformance();
			
			// remove current trader
			myPool.stock.removeTrader(trader);
			// collect earn
			totalEarn += earn;

			createNewTrader(myPool.getBestStrategy());
		}
	}
	
	private void createNewTrader(Strategy strategy) {

		// create new trader
		trader = new Trader("Trader", myPool.stock, strategy);
		trader.setLogTrading(true);
		// add to stock
		myPool.stock.addTrader(trader);
		// register listeners
		trader.setListener(this);

		log.info(" *** Switching to new strategy: "+strategy);
		log.info(" *** In the market time: "+inTheMarketTime);
		log.info(" *** OVERALL EARN: "+totalEarn);
		
		inTheMarketTime = 0;
	}
	
	@Override
	public void onBuy(Trader trader, float base, Rate rate) {
		log.info("BUYING MORE "+base);
	}
	@Override
	public void onSell(Trader trader, float quote, Rate rate) {
		log.info("SELLING "+quote);
	}


	@Override
	public void onStockOpen(Stock stock, int iteration, Rate rate) { }

	@Override
	public void onStockClose(Stock stock, int iteration, Rate rate) {
		inTheMarketTime++;	
		
		// display trader performane
		log.info("Trader performance: "+trader.evaluate(rate)+", Invested: "+trader.invested+" (max = "+trader.maxInvested+")"+
				", in the market "+inTheMarketTime);
	}
	
	
	private void showTraderPerformance() {

		int iter = myPool.stock.getCurrentIteration();
		RatesHistory period = myPool.stock.getRatesHistory().getPeriod(iter-inTheMarketTime, iter);
		
		Strategy strategy = trader.getStrategy();

		try {
			ChartDisplay.tradingChart("Strategy " + strategy, period, trader.getTradingHistory(),
					trader.getTradingHistory());
		} catch (Exception e) {
			log.error(e);
		}
	}
}
